package com.tanzc.mp3player;

import com.tanzc.mp3player.utils.ProcessUtil;
import javazoom.jl.decoder.JavaLayerException;
import sun.jvmstat.monitor.MonitorException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.URISyntaxException;
import java.nio.file.FileSystemException;
import java.util.Map;

/**
 * <p> description: description </p>
 *
 * @author tanzc
 * @date 10:27 2021/5/24
 **/
public class PlayerManager {

    ProcessUtil processUtil;

    Mp3Player mp3Player;

    PlayThread playThread;

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("invalid args number!");
            return;
        }

        PlayerManager playerManager = new PlayerManager();
        System.out.println("current process id: " + playerManager.getProcessId());
        try {
            playerManager.mainLogic(args);
        } catch (IOException | URISyntaxException | MonitorException e) {
            e.printStackTrace();
        }
    }


    public void mainLogic(String[] args) throws IOException, URISyntaxException, MonitorException {
        String args0 = args[0];
        int currentProcessId = getProcessId();
        switch (args0) {
            case "start":
                if (testAndKillOldManager(false, currentProcessId)) {
                    System.out.println("there is a manager already running,consider using the arg 'restart'!");
                    break;
                }
                startLogic();
                break;
            case "stop":
            case "kill":
                testAndKillOldManager(true, currentProcessId);
                break;
            case "restart":
                testAndKillOldManager(true, currentProcessId);
                startLogic();
                break;
            default:
                System.out.println("no supported operation!");
                break;
        }
    }

    public boolean testAndKillOldManager(boolean kill, int currentProcessId) throws IOException, URISyntaxException, MonitorException {
        boolean flag = false;
        Map<Object, String> vmMap = null;
        vmMap = processUtil.getAllRuningJava();
        for (Map.Entry<Object, String> entry : vmMap.entrySet()) {
            System.out.println(entry.getKey() + "-->" + entry.getValue());
            if (entry.getValue().contains("music-player.jar") && !entry.getKey().equals(currentProcessId)) {
                if (kill) {
                    processUtil.killProcess(Integer.parseInt(entry.getKey().toString()));
                }
                flag = true;
            }
        }
        return flag;
    }

    public void startLogic() {
        try {
            startMp3Player();
        } catch (FileSystemException | FileNotFoundException | JavaLayerException e) {
            e.printStackTrace();
        }
    }

    public void killLogic() {
        killMp3Player();
    }

    public PlayerManager() {
        mp3Player = new Mp3Player("I:\\Musics", "mp3");
        processUtil = new ProcessUtil();
        playThread = new PlayThread();
    }

    public boolean startMp3Player() throws FileSystemException, FileNotFoundException, JavaLayerException {
        playThread.start();

        return true;
    }

    public boolean killMp3Player() {
        if (playThread.isInterrupted()) {
            System.out.println("mp3player has be stopped!");
            return true;
        }
        mp3Player.stop();
        playThread.interrupt();
        return true;
    }

    class PlayThread extends Thread {
        @Override
        public void run() {
            // 由于mp3Player.playMp3Rotate中使用了死循环来循环播放音乐
            // 所以线程内部是阻塞的，这就导致一直没法读取中断标志位的。所以当前线程其实是无法终止的。
            // 可能的解决方法是：将mp3Player的死循环也单起一个线程。结束线程时，结束mp3Player里的线程，这样就不会阻塞了
            mp3Player.playMp3Rotate(new File(mp3Player.getMp3Dir()));
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("线程被中断，即将退出");
                    mp3Player.stopMp3Rotate();
                    break;
                }
            }
        }
    }

    public int getProcessId() {
        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
//        System.out.println(runtimeMxBean.getName());
        return Integer.parseInt(runtimeMxBean.getName().split("@")[0]);
    }
}
